#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>

using namespace std;
#define Page "index.html"

int main()
{
    // 创建套接字
    int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_sock < 0)
    {
        cout << "socket fail" << endl;
        exit(0);
    }

    // 填充结构体信息
    struct sockaddr_in local;
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(8081);
    local.sin_addr.s_addr = htonl(INADDR_ANY);

    // bind
    int n = bind(listen_sock, (struct sockaddr *)&local, sizeof(local));
    if (n < 0)
    {
        cout << "bind fail" << endl;
        exit(1);
    }

    // 监听
    n = listen(listen_sock, 5);
    if (n < 0)
    {
        cout << "listen fail" << endl;
        exit(2);
    }

    // 启动服务
    struct sockaddr_in peer;
    memset(&peer, 0, sizeof(peer));
    socklen_t len = sizeof(peer);
    while (true)
    {
        int sock = accept(listen_sock, (struct sockaddr *)&peer, &len);
        if (sock < 0)
        {
            cout << "accept fail" << endl;
            continue;
        }
        if(fork() == 0)
        {
            close(listen_sock);
            if(fork() > 0) exit(3);
            // 孙子进程办事
            char buffer[1024];
            recv(sock, buffer, sizeof(buffer), 0);//不要减1
            cout << "------------------http request begin----------------" << endl;
            cout << buffer << endl;
            cout << "------------------http request end----------------" << endl;
            // 读取html文件
            ifstream in(Page);
            if(in.is_open())
            {
                in.seekg(0, in.end);
                int len = in.tellg();
                in.seekg(0, in.beg);
                char *file = new char[len];
                in.read(file, len);
                in.close();

                // 构建http响应
                string status_line = "http/1.1 200 OK\n";//状态行
                string response_hander = "Content-Length: " + to_string(len) + "\n";//响应报头
                string blank = "\n";//空行
                string response_text = file;//响应正文
                string response = status_line + response_hander + blank + response_text;// 响应报文
                // 响应http请求
                send(sock, response.c_str(), response.size(), 0);
                delete[] file;
            }
            close(sock);
            exit(4);
        }
        close(sock);
        waitpid(-1, nullptr, 0);
    }

    return 0;
}